#define NANOPRINTF_CONVERSION_BUFFER_SIZE    512
#define NANOPRINTF_CONVERSION_FLOAT_TYPE    uint32_t

#include "unit_ftoa_rev.cc"

TEST_CASE("ftoa_rev_32") {
  memset(&spec, 0, sizeof(spec));

  SUBCASE("integer overflow") {
    spec.prec = 1;
    require_ftoa_rev("4294967295.5", (npf_ftoa_man_t)-1 + 0.5);
    require_ftoa_rev("4294967296.0", (npf_ftoa_man_t)-1 + 0.96875);
    require_ftoa_rev("4294967300.0", (npf_ftoa_man_t)-1 + 1.);
    require_ftoa_rev("4294967300.0", (npf_ftoa_man_t)-1 + 1.5);
    require_ftoa_rev("4294967300.0", (npf_ftoa_man_t)-1 + 9.);
    require_ftoa_rev("4294967310.0", (npf_ftoa_man_t)-1 + 10.);
  }

  SUBCASE("fraction accuracy") {
    spec.prec = 29 + 3;
    require_ftoa_rev("1.00000000186264514923095703125000", 1. + 1. / ((npf_double_bin_t)0x1 << (NPF_FTOA_MAN_BITS - 3)));
    require_ftoa_rev("0.99999999813735485076904296875000", 1. - 1. / ((npf_double_bin_t)0x1 << (NPF_FTOA_MAN_BITS - 3)));
    require_ftoa_rev("0.66666666679084300994873046875000", 2. / 3.);
    require_ftoa_rev("0.00000000000000000000066666666493", 2. / 3. / 1e21);
  }

  SUBCASE("limits") {
    // largest representable number
    require_ftoa_rev_bin(
      "17976929680000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "000000000000000000000000000000000000000000000000000000000000000000000",
      ((npf_double_bin_t)NPF_DOUBLE_EXP_MASK << NPF_DOUBLE_MAN_BITS) - 1);

    spec.prec = 346 + 3;

    // smallest normal number
    require_ftoa_rev_bin(
      "0.000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000022250737510"
      "6215476989746093750000000000000",
      (npf_double_bin_t)0x1 << NPF_DOUBLE_MAN_BITS);

    // largest subnormal number
    require_ftoa_rev_bin(
      "0.000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000022250737510"
      "6215476989746093750000000000000",
      ((npf_double_bin_t)0x1 << NPF_DOUBLE_MAN_BITS) - 1);

    // smallest representable numbers
    require_ftoa_rev_bin(
      "0.000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000016"
      "5780913084745407104492187500000",
      (npf_double_bin_t)0x3 << (NPF_DOUBLE_MAN_BITS - NPF_FTOA_MAN_BITS));

    require_ftoa_rev_bin(
      "0.000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000010"
      "3613070771098136901855468750000",
      (npf_double_bin_t)0x2 << (NPF_DOUBLE_MAN_BITS - NPF_FTOA_MAN_BITS));

    require_ftoa_rev_bin(
      "0.000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000000"
      "00000000000000000000000000000000000000000000000000000000000000000000000000000006"
      "2167842201888561248779296875000",
      (npf_double_bin_t)0x1 << (NPF_DOUBLE_MAN_BITS - NPF_FTOA_MAN_BITS));
  }
}
